# Methods for converting Fixnums between units
class Fixnum

  # Covert Plato to specific gravity
  #
  # @example
  #     14.to_specific_gravity
  #
  # @return [Float] degrees Plato
  def to_specific_gravity
    self.to_f.to_specific_gravity
  end

  # Covert Fahrenheit to Celsius
  #
  # @example
  #     104.to_celsius
  #
  # @return [Fixnum] temperature in Celsius
  def to_celsius
    ((self - 32) / 1.8).round
  end

  # Covert Celsius to Fahrenheit
  #
  # @example
  #     60.to_fahrenheit
  #
  # @return [Fixnum] temperature in Fahrenheit
  def to_fahrenheit
    ((self * 1.8) + 32).round
  end

  # Covert gallons (or quarts) to liters
  #
  # @example
  #     5.to_liters
  #     15.to_liters :quarts
  #
  # @return [Float] volume in liters
  def to_liters unit = :gallons
    self.to_f.to_liters unit
  end

  # Covert ounces to grams
  #
  # @example
  #     2.to_grams
  #
  # @return [Float] mass in grams
  def to_grams
    self.to_f.to_grams
  end

  # Covert grams to ounces
  #
  # @example
  #     56.to_ounces
  #
  # @return [Float] mass in ounces
  def to_ounces
    self.to_f.to_ounces
  end

  # Covert pounds to kilograms
  #
  # @example
  #     10.to_kilograms
  #
  # @return [Float] mass in kilograms
  def to_kilograms
    self.to_f.to_kilograms
  end

  # Covert kilograms to pounds
  #
  # @example
  #     10.to_pounds
  #
  # @return [Float] mass in pounds
  def to_pounds
    self.to_f.to_pounds
  end

  # Gravity correction based on sample temperature
  #
  # @note
  #     Temperature must be measured in Celsius
  #
  # @example
  #     40.gravity_correction
  #
  # @return [Float] mass in pounds
  def gravity_correction
    if self < 3.98
      -0.000032692 * self - 0.000740644
    elsif self < 50
      -0.0008031922 - 0.0000473773 * self + 0.000007231263 * self * self - 0.00000003078278 * self * self * self
    else
      -0.005431719 + 0.0001963596 * self + 0.000002661056 * self * self
    end
  end

end

# Methods for converting Floats between units
class Float

  # Covert specific gravity to Plato
  #
  # @example
  #     1.055.to_plato
  #
  # @return [Float] degrees Plato
  def to_plato
    (-676.67 + 1286.4 * self - 800.47 * self * self + 190.74 * self * self * self).round 1
  end

  # Covert Plato to specific gravity
  #
  # @example
  #     13.6.to_specific_gravity
  #
  # @return [Float] degrees Plato
  def to_specific_gravity
    (self / (258.6 - ((self / 258.2) * 227.1)) + 1.0).round 3
  end

  # Covert specific gravity to temperature corrected specific gravity
  #
  # @note
  #     Temperature must be measured in Celsius
  #
  # @example
  #     1.055.to_temperature_corrected_specific_gravity 40
  #
  # @param [Fixnum] temperature temperature of sample
  # @return [Float] temperature corrected specific gravity
  def to_temperature_corrected_specific_gravity temperature
    correction  = temperature.gravity_correction

    (self + correction).round 3
  end

  # Covert gallons (or quarts) to liters
  #
  # @example
  #     5.to_liters
  #     15.to_liters :quarts
  #
  # @return [Float] volume in liters
  def to_liters unit = :gallons
    case unit
    when :gallons
      (self * 3.785412).round 1
    when :quarts
      (self * 0.946353).round 1
    end
  end

  # Covert ounces to grams
  #
  # @example
  #     5.5.to_grams
  #
  # @return [Float] mass in grams
  def to_grams
    (self * 28.3495231).round 1
  end

  # Covert grams to ounces
  #
  # @example
  #     100.5.to_ounces
  #
  # @return [Float] mass in ounces
  def to_ounces
    (self * 0.0352739619).round 1
  end

  # Covert pounds to kilograms
  #
  # @example
  #     15.5.to_kilograms
  #
  # @return [Float] mass in kilograms
  def to_kilograms
    (self * 0.453592).round 1
  end

  # Covert kilograms to pounds
  #
  # @example
  #     7.5.to_pounds
  #
  # @return [Float] mass in pounds
  def to_pounds
    (self * 2.204623).round 1
  end

end
